''' <summary>
''' This is the underlying control which eliminates flickering by disabling painting of all
''' child and sub-controls.
''' </summary>
Public MustInherit Class FlickerFreeControl
    Inherits Control

    Private Const WM_SETREDRAW As Integer = &HB
    ''' <summary>
    ''' This is your good old SendMessage function.  We'll be sending the magic WM_SETREDRAW message which suspends and resumes painting for this and all sub controls.  Sweeto.
    ''' </summary>
    Private Declare Auto Function SendMessage Lib "User32" Alias "SendMessage" (ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Boolean

    Private mySuspendPainting As Integer = 0
    ''' <summary>
    ''' Stop painting while multiple changes are made to this and/or nested controls.
    ''' </summary>
    ''' <value>True to suspend painting.  False to resume painting.</value>
    ''' <remarks>This actually increments a counter for each time it is set to true and decrements that 
    ''' counter for each time it is set to false.  This is to prevent painting from resuming earlier than
    ''' we might wish.</remarks>
    Protected Property SuspendPainting() As Boolean
        Get
            Return mySuspendPainting > 0
        End Get
        Set(ByVal value As Boolean)
            If (Not Me.Visible OrElse Not Me.IsHandleCreated) Then Exit Property
            If (value) Then
                mySuspendPainting += 1
                If (System.Threading.Interlocked.Increment(mySuspendPainting) = 1) Then
                    SendMessage(Me.Handle, WM_SETREDRAW, 0, 0)
                End If
            Else
                If (System.Threading.Interlocked.Decrement(mySuspendPainting) = 0) Then
                    SendMessage(Me.Handle, WM_SETREDRAW, 1, 0)
                    Me.Invalidate(True)
                End If
            End If
        End Set
    End Property

    Public Sub New()
        Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
        Me.SetStyle(ControlStyles.UserPaint, True)
        Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
    End Sub
End Class
